function varargout = analysisgui(varargin)
% ANALYSISGUI MATLAB code for analysisgui.fig
%      ANALYSISGUI, by itself, creates a new ANALYSISGUI or raises the existing
%      singleton*.
%
%      H = ANALYSISGUI returns the handle to a new ANALYSISGUI or the handle to
%      the existing singleton*.
%
%      ANALYSISGUI('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in ANALYSISGUI.M with the given input arguments.
%
%      ANALYSISGUI('Property','Value',...) creates a new ANALYSISGUI or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before analysisgui_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to analysisgui_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help analysisgui

% Last Modified by GUIDE v2.5 31-Oct-2012 13:11:50

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @analysisgui_OpeningFcn, ...
                   'gui_OutputFcn',  @analysisgui_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT

% --- Executes just before analysisgui is made visible.
function analysisgui_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
addpath(genpath('hough_transform'));

set(handles.statustext,'String','Click on Open to select an image');
guidata(hObject, handles);


% --- Outputs from this function are returned to the command line.
function varargout = analysisgui_OutputFcn(hObject, eventdata, handles)
varargout{1} = handles.output;


% --------------------------------------------------------------------
function FileMenu_Callback(hObject, eventdata, handles)
% hObject    handle to FileMenu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% --------------------------------------------------------------------
function OpenMenuItem_Callback(hObject, eventdata, handles)
% hObject    handle to OpenMenuItem (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
file = uigetfile('*.fig');
if ~isequal(file, 0)
    open(file);
end

% --------------------------------------------------------------------
function PrintMenuItem_Callback(hObject, eventdata, handles)
% hObject    handle to PrintMenuItem (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
printdlg(handles.figure1)

% --------------------------------------------------------------------
function CloseMenuItem_Callback(hObject, eventdata, handles)
% hObject    handle to CloseMenuItem (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
selection = questdlg(['Close ' get(handles.figure1,'Name') '?'],...
                     ['Close ' get(handles.figure1,'Name') '...'],...
                     'Yes','No','Yes');
if strcmp(selection,'No')
    return;
end

delete(handles.figure1)


% --- Executes on selection change in popupmenu1.
function popupmenu1_Callback(hObject, eventdata, handles)
% hObject    handle to popupmenu1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = get(hObject,'String') returns popupmenu1 contents as cell array
%        contents{get(hObject,'Value')} returns selected item from popupmenu1


% --- Executes during object creation, after setting all properties.
function popupmenu1_CreateFcn(hObject, eventdata, handles)
% hObject    handle to popupmenu1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
     set(hObject,'BackgroundColor','white');
end

set(hObject, 'String', {'plot(rand(5))', 'plot(sin(1:0.01:25))', 'bar(1:.5:10)', 'plot(membrane)', 'surf(peaks)'});


% --- Executes on button press in openbutton.
function openbutton_Callback(hObject, eventdata, handles)
[file_name,path_name] = uigetfile({'*.jpg','*.png'},'Select an image');
hold off;
I = imread(fullfile(path_name,file_name));
imshow(I); axis auto;
drawnow;
hold on;
h = waitbar(.3,'Extracting iris...');

set(handles.statustext,'String','Extracting iris...')
[center,radius] = circularhough(I,.5,false);
drawnow;

h = waitbar(.7,h,'Extracting eyelids...');
set(handles.statustext,'String','Extracting lower_disteyelids')
eyelid_points = detect_eyelid(I,[center(2) center(1)],radius,true);
close(h);
hold on;
[px, py] = circlepoints(radius);
px = px + center(2);
py = py + center(1);
handles.iris_plot = plot(px,py,'LineWidth',5);
upper_eyelid = eyelid_points(1:5,1:2);
lower_eyelid = eyelid_points(6:end,1:2);
upper_range = upper_eyelid(1,1):.1:upper_eyelid(5,1);
upper_yy = spline(upper_eyelid(:,1),upper_eyelid(:,2),upper_range);
lower_range = lower_eyelid(1,1):.1:lower_eyelid(5,1);
lower_yy = spline(lower_eyelid(:,1),lower_eyelid(:,2),lower_range);
hold on;
handles.upperlid_plot = plot(upper_range,upper_yy,'LineWidth',5);
handles.lowerlid_plot = plot(lower_range,lower_yy,'LineWidth',5);

handles.upper_data = upper_eyelid;
handles.lower_data = lower_eyelid;
handles.iris_data = [center(2) center(1) radius];
handles.upper_curve = [upper_range; upper_yy];
handles.lower_curve = [lower_range; lower_yy];
set(handles.adjustbutton,'Enable','on');
%set(handles.predictionoverlaycheckbox,'Visible','on');

guidata(hObject, handles);

% --- Executes on button press in adjustbutton.
function adjustbutton_Callback(hObject, eventdata, handles)
% Show the drop down
set(handles.dropdown,'Visible','on');
set(handles.donebutton,'Visible','on');
set(handles.dropdown,'Enable','on');
set(handles.donebutton,'Enable','on');
set(handles.openbutton,'Enable','off');
set(handles.selectnormalbutton,'Enable','off');
set(hObject,'Enable','off');
guidata(hObject, handles);


% --- Executes on button press in selectnormalbutton.
function selectnormalbutton_Callback(hObject, eventdata, handles)
file_name = uigetfile({'*.mat','Select a normal binary'});
%set(handles.normaloverlaycheckbox,'Visible','on');
load(file_name);
px = handles.iris_data(1);
py = handles.iris_data(2);
radius = handles.iris_data(3);

handles.upperlid_normal = upper_eyelid_normal;
handles.lowerlid_normal = lower_eyelid_normal;
handles.normal_radius = average_radius;

ratio = radius/handles.normal_radius;
upperlid_normal = handles.upperlid_normal * ratio;
lowerlid_normal = handles.lowerlid_normal * ratio;

upperlid_normal(:,1) = upperlid_normal(:,1) + px;
upperlid_normal(:,2) = upperlid_normal(:,2) + py;
lowerlid_normal(:,1) = lowerlid_normal(:,1) + px;
lowerlid_normal(:,2) = lowerlid_normal(:,2) + py;

plot(upperlid_normal(:,1),upperlid_normal(:,2),'ro');
plot(lowerlid_normal(:,1),lowerlid_normal(:,2),'ro');

[maxr,~] = size(upper_eyelid_normal);
upper_range_normal = upperlid_normal(1,1):.1:upperlid_normal(maxr,1);
upper_yy_normal = spline(upperlid_normal(:,1),upperlid_normal(:,2),upper_range_normal);

lower_range_normal = lowerlid_normal(1,1):.1:lowerlid_normal(maxr,1);
lower_yy_normal = spline(lowerlid_normal(:,1),lowerlid_normal(:,2),lower_range_normal);

hold on
plot(upper_range_normal,upper_yy_normal,'r');
plot(lower_range_normal,lower_yy_normal,'r');
upper_eyelid = handles.upper_data;
lower_eyelid = handles.lower_data;

[maxr,~] = size(upper_eyelid);

upper_yy = spline(upper_eyelid(:,1),upper_eyelid(:,2),upper_range_normal);
lower_yy = spline(lower_eyelid(:,1),lower_eyelid(:,2),lower_range_normal);

upper_dist = (sum(((upper_yy - upper_yy_normal)/radius).^2))/length(upper_yy);
lower_dist = (sum(((lower_yy - lower_yy_normal)/radius).^2))/length(lower_yy);

sdfrac_upper = upper_dist/sd_upper_dists;
sdfrac_lower = lower_dist/sd_lower_dists;

set(handles.statustext,'String',sprintf('Upper distance: %f sd from the mean\nLower distance: %f sd from the mean\n',sdfrac_upper,sdfrac_lower));

% --- Executes on selection change in dropdown.
function dropdown_Callback(hObject, eventdata, handles)
% hObject    handle to dropdown (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

contents = get(hObject,'String');
selection = contents{get(hObject,'Value')};

handles.upper_control = cell(1,size(handles.upper_data,1));
handles.lower_control = cell(1,size(handles.lower_data,1));

delete(handles.iris_plot)
if strcmp(selection,'upperlid')
    delete(handles.lowerlid_plot)
    for i=1:size(handles.upper_data,1)
        point_handle = impoint(gca,handles.upper_data(i,:));
        setString(point_handle,i);
        setColor(point_handle,'r');
        handles.upper_control{i} = point_handle;
        addNewPositionCallback(point_handle,@(pos) redraw(pos,i,true));
    end
elseif strcmp(selection,'lowerlid')
    delete(handles.upperlid_plot)
    for i=1:size(handles.lower_data,1)
        point_handle = impoint(gca,handles.lower_data(i,:));
        setString(point_handle,i);
        setColor(point_handle,'r');
        handles.lower_control{i} = point_handle;
        addNewPositionCallback(point_handle,@(pos) redraw(pos,i,false));
    end
elseif strcmp(selection,'iris')
    radius = handles.iris_data(3);
    minx = handles.iris_data(1) - handles.iris_data(3);
    miny = handles.iris_data(2) - handles.iris_data(3);
    width = 2*radius;
    bb = [minx miny width width];
    h = imellipse(gca,bb);
    h.setFixedAspectRatioMode(true);
    handles.iris_handle = h;
end
guidata(hObject, handles);


% --- Executes during object creation, after setting all properties.
function dropdown_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

set(hObject, 'String', {'choose one to edit...','upperlid','lowerlid','iris'});


% --- Executes on button press in donebutton.
function donebutton_Callback(hObject, eventdata, handles)
% hObject    handle to donebutton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
set(handles.openbutton,'Enable','on');
set(handles.adjustbutton,'Enable','on');
set(handles.selectnormalbutton,'Enable','on');
set(handles.donebutton,'Enable','off');
set(handles.dropdown,'Value',1);
set(handles.dropdown,'Enable','off');

try
    for i=1:length(handles.upper_control)
        delete(handles.upper_control{i});
    end
    delete(handles.upper1);
catch exception
    exception
end

try
    for i=1:length(handles.lower_control)
        delete(handles.lower_control{i});
    end
    
    delete(handles.lower1);
catch exception
    exception
end

try
    iris_handle = handles.iris_handle;
    iris_position = iris_handle.getPosition();
    radius = floor(iris_position(3)/2);
    xc = iris_position(1) + floor(iris_position(3)/2);
    yc = iris_position(2) + floor(iris_position(3)/2);
    handles.iris_data = [xc yc radius];
    delete(handles.iris_handle);
catch exception
    exception
end

% Redraw the image
iris_data = handles.iris_data;
upper_eyelid = handles.upper_data;
lower_eyelid = handles.lower_data;

xc_iris = iris_data(1); yc_iris = iris_data(2);
radius_iris = iris_data(3);
[px, py] = circlepoints(radius_iris);

[maxr,~] = size(upper_eyelid);

upper_range = upper_eyelid(1,1):.1:upper_eyelid(maxr,1);
upper_yy = spline(upper_eyelid(:,1),upper_eyelid(:,2),upper_range);

lower_range = lower_eyelid(1,1):.1:lower_eyelid(maxr,1);
lower_yy = spline(lower_eyelid(:,1),lower_eyelid(:,2),lower_range);

px = px + xc_iris;
py = py + yc_iris;

% Draw the guesses
hold on
handles.iris_plot = plot(px,py,'LineWidth',5);
handles.upperlid_plot = plot(upper_range,upper_yy,'LineWidth',5);
handles.lowerlid_plot = plot(lower_range,lower_yy,'LineWidth',5);

guidata(hObject, handles);

function redraw(pos,i,upper)
% Delete the existing plot

handles = guidata(gcf);
if upper
    delete(handles.upperlid_plot);
    data = handles.upper_data;
    data(i,:) = pos;
    data_range = data(1,1):.1:data(5,1);
    yy = spline(data(:,1),data(:,2),data_range);
    handles.upperlid_plot = plot(data_range,yy,'LineWidth',5);
    uistack(handles.upperlid_plot,'down',5)
    handles.upper_data = data;
else
    delete(handles.lowerlid_plot);
    data = handles.lower_data;
    data(i,:) = pos;
    data_range = data(1,1):.1:data(5,1);
    yy = spline(data(:,1),data(:,2),data_range);
    plot_handle = plot(data_range,yy,'LineWidth',5);
    handles.lowerlid_plot = plot_handle;
    uistack(handles.lowerlid_plot,'down',6)
    handles.lower_data = data;
end

guidata(gcf,handles);


% --- Executes on button press in predictionoverlaycheckbox.
function predictionoverlaycheckbox_Callback(hObject, eventdata, handles)
% hObject    handle to predictionoverlaycheckbox (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of predictionoverlaycheckbox

if checked
    % Draw the object
else
    % Delete it
end

% --- Executes on button press in normaloverlaycheckbox.
function normaloverlaycheckbox_Callback(hObject, eventdata, handles)
